/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.actions.delete;

import java.util.Iterator;
import java.util.List;

import org.eclipse.gef.EditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;

import com.cea.papyrus.core.editpart.IUMLElementEditPart;
import com.cea.papyrus.core.editpart.IUMLObjectEditPart;
import com.cea.papyrus.core.utils.Debug;

/**
 * Action which deletes the selection from the model
 */
public class DeleteFromModelAction extends org.eclipse.gef.ui.actions.SelectionAction {

	/** request key for the request associated to this action  */
	public final static String DELETE_FROM_MODEL_ACTION_REQUEST = "testdeletefrommodelrequest";
	
	/** ID of  this action */
	public final static String DELETE_FROM_MODEL_ACTION_ID = "testdeletefrommodel";
	
	/** Request created by this action */
	protected Request request;
	
	/**
	 * Creates a new DeleteFromModelAction
	 * @param part that part which contains the selection
	 */
	public DeleteFromModelAction(IWorkbenchPart part) {
		super(part);
		request = new Request(DELETE_FROM_MODEL_ACTION_REQUEST);
		setText("Delete From Model");
		setId(DELETE_FROM_MODEL_ACTION_ID);
		setToolTipText("Delete element(s) from the model");
		ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages();
		setImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));
		setHoverImageDescriptor(getImageDescriptor());
		
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.ui.actions.WorkbenchPartAction#calculateEnabled()
	 */
	@Override
	protected boolean calculateEnabled() {
		return canPerformAction();
	}	
	
	/**
	 * Check if the action can be performed or not 
	 * @return <code>true</code> if the operation can be executed
	 */
	private boolean canPerformAction() {
		
		if (getSelectedObjects().isEmpty()) {
			return false;
		}
		List parts = getSelectedObjects();
		for (int i=0; i<parts.size(); i++){
			Object o = parts.get(i);
			if (!(o instanceof IUMLObjectEditPart)) {
				return false;
			} else {
				// if element is a IUMLElementEditPart,and no model element is associated, return false
				if(o instanceof IUMLElementEditPart) {
					if ( ((IUMLElementEditPart)o).getUmlElement()== null ) {
						return false;
					}
				}
			}
		}
		return true;
	}
	
	/**
	 * Returns the command that will delete the selected elements 
	 * @return the command that will delete the selected elements 
	 */
	private Command getCommand() {
		List editparts = getSelectedObjects();
		CompoundCommand cc = new CompoundCommand();
		Debug.debug(this,"Action::getCommand()"+editparts.size(), 21);
		for (int i=0; i < editparts.size(); i++) {
			EditPart part = (EditPart) editparts.get(i);
			cc.add(part.getCommand(request));
		}
		displayCompoundCommand(cc);
		return cc;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.action.Action#run()
	 */
	@Override
	public void run () {
		// open dialog window
		 BusyIndicator.showWhile(Display.getCurrent(), new Runnable() {
            public void run() {
            	execute(getCommand());
            }
        });
	}
	
	 /* (non-Javadoc)
	 * @see org.eclipse.gef.ui.actions.SelectionAction#setSelection(org.eclipse.jface.viewers.ISelection)
	 */
	@Override
	public void setSelection(ISelection selection) {
		// overrides for visibility
		super.setSelection(selection);
	}
	
	/**
	 * Debug method to display the commands that compose a compound command
	 * @param command the compound command to display 
	 */
	void displayCompoundCommand(CompoundCommand command) {
		Iterator<Command> it = command.getCommands().iterator();
		while(it.hasNext()) {
			displayCommand(it.next());
		}
	}
	
	/**
	 * Debug method to display a command
	 * @param command the command to display 
	 */
	void displayCommand(Command command) {
		if(command instanceof CompoundCommand) {
			displayCompoundCommand((CompoundCommand)command);
		} else {
			Debug.debug(this, command.toString(), 21);
		}
	}
}
